/**
 * @file tcu.c
 * @brief TCU设备主实现文件
 * @details 实现TCU设备的核心功能，包括设备管理、MQTT通信、数据上报等
 * @author 开发者
 * @date 2024
 * @version 1.0.0
 */

#include "tcu.h"
#include "../../log/logger.h"
#include <unistd.h>
#include <sys/time.h>

/**
 * @name 内部函数声明
 * @{
 */
static int load_device_config(tcu_t *tcu);           /**< 加载设备配置 */
static int load_mqtt_config(tcu_t *tcu);             /**< 加载MQTT配置 */
static int load_data_config(tcu_t *tcu);             /**< 加载数据配置 */
static void* data_report_thread_func(void *arg);     /**< 数据上报线程函数 */
static void* heartbeat_thread_func(void *arg);       /**< 心跳线程函数 */
/** @} */
static int64_t get_current_timestamp_ms(void);

/**
 * @brief 初始化TCU设备
 * @details 初始化TCU设备，包括配置管理器、设备配置、MQTT配置等
 * @param tcu TCU设备结构指针
 * @param config_dir 配置目录路径
 * @return 成功返回0，失败返回-1
 */
int tcu_init(tcu_t *tcu, const char *config_dir) {
    // 1. 参数验证
    if (!tcu || !config_dir) {
        LOG_ERROR("参数错误");
        return -1;
    }
    
    // 2. 初始化TCU结构体
    memset(tcu, 0, sizeof(tcu_t));
    
    // 3. 初始化配置管理器
    if (config_manager_init(&tcu->config_manager, config_dir) != 0) {
        LOG_ERROR("配置管理器初始化失败");
        return -1;
    }
    
    // 4. 加载设备配置
    if (load_device_config(tcu) != 0) {
        LOG_ERROR("设备配置加载失败");
        config_manager_cleanup(&tcu->config_manager);
        return -1;
    }
    
    // 5. 加载MQTT配置
    if (load_mqtt_config(tcu) != 0) {
        LOG_ERROR("MQTT配置加载失败");
        config_manager_cleanup(&tcu->config_manager);
        return -1;
    }
    
    // 6. 加载数据配置
    if (load_data_config(tcu) != 0) {
        LOG_ERROR("数据配置加载失败");
        config_manager_cleanup(&tcu->config_manager);
        return -1;
    }
    
    // 7. 初始化状态互斥锁
    if (pthread_mutex_init(&tcu->state_mutex, NULL) != 0) {
        LOG_ERROR("状态互斥锁初始化失败");
        config_manager_cleanup(&tcu->config_manager);
        return -1;
    }
    
    // 8. 初始化数据互斥锁
    if (pthread_mutex_init(&tcu->data_mutex, NULL) != 0) {
        LOG_ERROR("数据互斥锁初始化失败");
        pthread_mutex_destroy(&tcu->state_mutex);
        config_manager_cleanup(&tcu->config_manager);
        return -1;
    }
    
    // 设置初始状态
    tcu->state = TCU_STATE_INIT;
    tcu->start_time = get_current_timestamp_ms();
    tcu->running = false;
    tcu->should_reconnect = false;
    
    LOG_INFO("TCU设备初始化完成");
    LOG_INFO("产品Key: %s", tcu->device_info.product_key);
    LOG_INFO("设备名称: %s", tcu->device_info.device_name);
    LOG_INFO("MQTT服务器: %s:%d", tcu->mqtt_config.broker_host, tcu->mqtt_config.broker_port);
    
    return 0;
}

// 清理TCU设备
void tcu_cleanup(tcu_t *tcu) {
    if (!tcu) {
        return;
    }
    
    // 停止设备
    tcu_stop(tcu);
    
    // 销毁互斥锁
    pthread_mutex_destroy(&tcu->state_mutex);
    pthread_mutex_destroy(&tcu->data_mutex);
    
    // 清理配置管理器
    config_manager_cleanup(&tcu->config_manager);
    
    LOG_INFO("TCU设备清理完成");
}

// 启动TCU设备
int tcu_start(tcu_t *tcu) {
    if (!tcu) {
        return -1;
    }
    
    pthread_mutex_lock(&tcu->state_mutex);
    
    if (tcu->running) {
        LOG_WARN("TCU设备已经在运行中");
        pthread_mutex_unlock(&tcu->state_mutex);
        return 0;
    }
    
    tcu->running = true;
    tcu->state = TCU_STATE_DISCONNECTED;
    
    // 启动数据上报线程
    if (pthread_create(&tcu->data_report_thread, NULL, data_report_thread_func, tcu) != 0) {
        LOG_ERROR("数据上报线程创建失败");
        tcu->running = false;
        pthread_mutex_unlock(&tcu->state_mutex);
        return -1;
    }
    
    // 启动心跳线程
    if (pthread_create(&tcu->heartbeat_thread, NULL, heartbeat_thread_func, tcu) != 0) {
        LOG_ERROR("心跳线程创建失败");
        tcu->running = false;
        pthread_cancel(tcu->data_report_thread);
        pthread_join(tcu->data_report_thread, NULL);
        pthread_mutex_unlock(&tcu->state_mutex);
        return -1;
    }
    
    pthread_mutex_unlock(&tcu->state_mutex);
    
    LOG_INFO("TCU设备启动成功");
    return 0;
}

// 停止TCU设备
void tcu_stop(tcu_t *tcu) {
    if (!tcu) {
        return;
    }
    
    pthread_mutex_lock(&tcu->state_mutex);
    
    if (!tcu->running) {
        pthread_mutex_unlock(&tcu->state_mutex);
        return;
    }
    
    tcu->running = false;
    tcu->state = TCU_STATE_SHUTDOWN;
    
    pthread_mutex_unlock(&tcu->state_mutex);
    
    // 等待线程结束
    pthread_join(tcu->data_report_thread, NULL);
    pthread_join(tcu->heartbeat_thread, NULL);
    
    LOG_INFO("TCU设备停止完成");
}

// 设置设备状态
void tcu_set_state(tcu_t *tcu, tcu_state_t state) {
    if (!tcu) {
        return;
    }
    
    pthread_mutex_lock(&tcu->state_mutex);
    tcu_state_t old_state = tcu->state;
    tcu->state = state;
    pthread_mutex_unlock(&tcu->state_mutex);
    
    if (old_state != state) {
        LOG_INFO("设备状态变更: %s -> %s", tcu_state_to_string(old_state), tcu_state_to_string(state));
    }
}

// 获取设备状态
tcu_state_t tcu_get_state(tcu_t *tcu) {
    if (!tcu) {
        return TCU_STATE_ERROR;
    }
    
    pthread_mutex_lock(&tcu->state_mutex);
    tcu_state_t state = tcu->state;
    pthread_mutex_unlock(&tcu->state_mutex);
    
    return state;
}

// 设备注册
int tcu_device_register(tcu_t *tcu, const char *type) {
    if (!tcu || !type) {
        return -1;
    }
    
    LOG_INFO("开始设备注册，类型: %s", type);
    
    // 获取注册模板
    cJSON *template = cJSON_GetObjectItem(tcu->config_manager.message_templates, "device_register");
    if (!template) {
        LOG_ERROR("未找到设备注册模板");
        return -1;
    }
    
    // 创建注册消息
    cJSON *message = cJSON_CreateObject();
    if (!message) {
        LOG_ERROR("创建注册消息失败");
        return -1;
    }
    
    // 生成消息ID
    char msg_id[64];
    snprintf(msg_id, sizeof(msg_id), "%ld", get_current_timestamp_ms());
    
    // 填充消息内容
    cJSON_AddStringToObject(message, "id", msg_id);
    cJSON_AddStringToObject(message, "type", type);
    cJSON_AddStringToObject(message, "productKey", tcu->device_info.product_key);
    cJSON_AddStringToObject(message, "deviceName", tcu->device_info.device_name);
    cJSON_AddStringToObject(message, "deviceSecret", tcu->device_info.device_secret);
    
    if (strcmp(type, "signup") == 0) {
        cJSON_AddStringToObject(message, "productSecret", tcu->device_info.product_secret);
    }
    
    // 序列化消息
    char *json_string = cJSON_Print(message);
    cJSON_Delete(message);
    
    if (!json_string) {
        LOG_ERROR("消息序列化失败");
        return -1;
    }
    
    LOG_INFO("设备注册消息: %s", json_string);
    
    // TODO: 发送MQTT消息
    free(json_string);
    
    tcu_set_state(tcu, TCU_STATE_REGISTERING);
    return 0;
}

// 设备注销
int tcu_device_unregister(tcu_t *tcu) {
    return tcu_device_register(tcu, "unregister");
}

// 获取物模型
int tcu_get_thing_model(tcu_t *tcu, const char *model_type) {
    if (!tcu || !model_type) {
        return -1;
    }
    
    LOG_INFO("获取物模型，类型: %s", model_type);
    
    // 创建请求消息
    cJSON *message = cJSON_CreateObject();
    if (!message) {
        LOG_ERROR("创建物模型请求消息失败");
        return -1;
    }
    
    // 生成消息ID
    char msg_id[64];
    snprintf(msg_id, sizeof(msg_id), "%ld", get_current_timestamp_ms());
    
    // 填充消息内容
    cJSON_AddStringToObject(message, "id", msg_id);
    cJSON_AddStringToObject(message, "type", model_type);
    cJSON_AddStringToObject(message, "productKey", tcu->device_info.product_key);
    
    // 序列化消息
    char *json_string = cJSON_Print(message);
    cJSON_Delete(message);
    
    if (!json_string) {
        LOG_ERROR("消息序列化失败");
        return -1;
    }
    
    LOG_INFO("物模型请求消息: %s", json_string);
    
    // TODO: 发送MQTT消息
    free(json_string);
    
    return 0;
}

// 上报属性数据
int tcu_report_properties(tcu_t *tcu, cJSON *properties) {
    if (!tcu || !properties) {
        return -1;
    }
    
    // 创建上报消息
    cJSON *message = cJSON_Duplicate(properties, 1);
    if (!message) {
        LOG_ERROR("复制属性数据失败");
        return -1;
    }
    
    // 添加上报时间
    cJSON_AddNumberToObject(message, "reportTime", get_current_timestamp_ms());
    
    // 序列化消息
    char *json_string = cJSON_Print(message);
    cJSON_Delete(message);
    
    if (!json_string) {
        LOG_ERROR("消息序列化失败");
        return -1;
    }
    
    LOG_INFO("属性上报消息: %s", json_string);
    
    // TODO: 发送MQTT消息
    free(json_string);
    
    return 0;
}

// 上报单个属性
int tcu_report_property(tcu_t *tcu, const char *identifier, const char *value) {
    if (!tcu || !identifier || !value) {
        return -1;
    }
    
    cJSON *properties = cJSON_CreateObject();
    if (!properties) {
        return -1;
    }
    
    cJSON_AddStringToObject(properties, identifier, value);
    
    int result = tcu_report_properties(tcu, properties);
    cJSON_Delete(properties);
    
    return result;
}

// 上报事件
int tcu_report_event(tcu_t *tcu, const char *identifier, cJSON *output_data, const char *call_type) {
    if (!tcu || !identifier || !output_data || !call_type) {
        return -1;
    }
    
    LOG_INFO("上报事件: %s", identifier);
    
    // 创建事件消息
    cJSON *message = cJSON_CreateObject();
    if (!message) {
        LOG_ERROR("创建事件消息失败");
        return -1;
    }
    
    // 生成事件ID
    char event_id[64];
    snprintf(event_id, sizeof(event_id), "%ld", get_current_timestamp_ms());
    
    // 填充消息内容
    cJSON_AddNumberToObject(message, "reportTime", get_current_timestamp_ms());
    cJSON_AddStringToObject(message, "id", event_id);
    cJSON_AddStringToObject(message, "callType", call_type);
    cJSON_AddStringToObject(message, "identifier", identifier);
    cJSON_AddItemToObject(message, "outputData", cJSON_Duplicate(output_data, 1));
    
    // 序列化消息
    char *json_string = cJSON_Print(message);
    cJSON_Delete(message);
    
    if (!json_string) {
        LOG_ERROR("消息序列化失败");
        return -1;
    }
    
    LOG_INFO("事件上报消息: %s", json_string);
    
    // TODO: 发送MQTT消息
    free(json_string);
    
    return 0;
}

// 处理属性设置
int tcu_handle_property_set(tcu_t *tcu, const char *identifier, const char *value) {
    if (!tcu || !identifier || !value) {
        return -1;
    }
    
    LOG_INFO("处理属性设置: %s = %s", identifier, value);
    
    // TODO: 实现属性设置逻辑
    
    return 0;
}

// 处理服务调用
int tcu_handle_service_call(tcu_t *tcu, const char *identifier, cJSON *input_params, cJSON *output_params) {
    if (!tcu || !identifier || !input_params || !output_params) {
        return -1;
    }
    
    LOG_INFO("处理服务调用: %s", identifier);
    
    // TODO: 实现服务调用逻辑
    
    return 0;
}

// 处理设备升级
int tcu_handle_device_update(tcu_t *tcu, cJSON *update_data) {
    if (!tcu || !update_data) {
        return -1;
    }
    
    LOG_INFO("处理设备升级");
    
    // TODO: 实现设备升级逻辑
    
    return 0;
}

// 打印设备统计信息
void tcu_print_stats(tcu_t *tcu) {
    if (!tcu) {
        return;
    }
    
    int64_t uptime = tcu_get_uptime(tcu);
    
    LOG_INFO("=== TCU设备统计信息 ===");
    LOG_INFO("运行时间: %ld 秒", uptime);
    LOG_INFO("当前状态: %s", tcu_state_to_string(tcu->state));
    LOG_INFO("发送消息数: %d", tcu->message_sent_count);
    LOG_INFO("接收消息数: %d", tcu->message_received_count);
    LOG_INFO("重连次数: %d", tcu->reconnect_count);
    LOG_INFO("========================");
}

// 获取设备运行时间
int64_t tcu_get_uptime(tcu_t *tcu) {
    if (!tcu) {
        return 0;
    }
    
    int64_t current_time = get_current_timestamp_ms();
    return (current_time - tcu->start_time) / 1000;
}

// 状态转字符串
const char* tcu_state_to_string(tcu_state_t state) {
    switch (state) {
        case TCU_STATE_INIT: return "初始化";
        case TCU_STATE_DISCONNECTED: return "断开连接";
        case TCU_STATE_CONNECTING: return "连接中";
        case TCU_STATE_CONNECTED: return "已连接";
        case TCU_STATE_REGISTERING: return "注册中";
        case TCU_STATE_REGISTERED: return "已注册";
        case TCU_STATE_RUNNING: return "运行中";
        case TCU_STATE_ERROR: return "错误状态";
        case TCU_STATE_SHUTDOWN: return "关闭中";
        default: return "未知状态";
    }
}

/**
 * @brief 设置消息回调函数
 * @details 设置TCU设备接收MQTT消息时的回调处理函数
 * @param tcu TCU设备结构指针
 * @param callback 消息回调函数指针
 */
void tcu_set_message_callback(tcu_t *tcu, tcu_message_callback_t callback) {
    (void)tcu;      // 避免未使用参数警告
    (void)callback; // 避免未使用参数警告
    // TODO: 实现消息回调设置
}

/**
 * @brief 设置连接回调函数
 * @details 设置TCU设备连接MQTT代理成功时的回调处理函数
 * @param tcu TCU设备结构指针
 * @param callback 连接回调函数指针
 */
void tcu_set_connect_callback(tcu_t *tcu, tcu_connect_callback_t callback) {
    (void)tcu;      // 避免未使用参数警告
    (void)callback; // 避免未使用参数警告
    // TODO: 实现连接回调设置
}

/**
 * @brief 设置断开连接回调函数
 * @details 设置TCU设备断开MQTT代理连接时的回调处理函数
 * @param tcu TCU设备结构指针
 * @param callback 断开连接回调函数指针
 */
void tcu_set_disconnect_callback(tcu_t *tcu, tcu_disconnect_callback_t callback) {
    (void)tcu;      // 避免未使用参数警告
    (void)callback; // 避免未使用参数警告
    // TODO: 实现断开连接回调设置
}

/**
 * @brief 加载设备配置
 * @details 从配置文件中加载设备信息，包括产品密钥、设备名称等
 * @param tcu TCU设备结构指针
 * @return 成功返回0，失败返回-1
 */
static int load_device_config(tcu_t *tcu) {
    // 1. 检查设备配置是否存在
    if (!tcu->config_manager.device_config) {
        return -1;
    }
    
    // 2. 获取设备配置对象
    cJSON *device = cJSON_GetObjectItem(tcu->config_manager.device_config, "device");
    if (!device) {
        return -1;
    }
    
    // 3. 加载产品密钥
    strncpy(tcu->device_info.product_key, 
            config_get_string(device, "productKey", ""), 
            sizeof(tcu->device_info.product_key) - 1);
    
    // 4. 加载设备名称
    strncpy(tcu->device_info.device_name, 
            config_get_string(device, "deviceName", ""), 
            sizeof(tcu->device_info.device_name) - 1);
    
    strncpy(tcu->device_info.device_secret, 
            config_get_string(device, "deviceSecret", ""), 
            sizeof(tcu->device_info.device_secret) - 1);
    
    strncpy(tcu->device_info.product_secret, 
            config_get_string(device, "productSecret", ""), 
            sizeof(tcu->device_info.product_secret) - 1);
    
    // 生成客户端ID
    int ret = snprintf(tcu->device_info.client_id, sizeof(tcu->device_info.client_id), 
                      "tcu_%s_%ld", tcu->device_info.device_name, get_current_timestamp_ms());
    if (ret >= (int)sizeof(tcu->device_info.client_id)) {
        // 截断处理，确保字符串以null结尾
        tcu->device_info.client_id[sizeof(tcu->device_info.client_id) - 1] = '\0';
    }
    
    return 0;
}

static int load_mqtt_config(tcu_t *tcu) {
    if (!tcu->config_manager.device_config) {
        return -1;
    }
    
    cJSON *mqtt = cJSON_GetObjectItem(tcu->config_manager.device_config, "mqtt");
    if (!mqtt) {
        return -1;
    }
    
    strncpy(tcu->mqtt_config.broker_host, 
            config_get_string(mqtt, "broker_host", "localhost"), 
            sizeof(tcu->mqtt_config.broker_host) - 1);
    
    tcu->mqtt_config.broker_port = config_get_int(mqtt, "broker_port", 1883);
    tcu->mqtt_config.keepalive = config_get_int(mqtt, "keepalive", 60);
    tcu->mqtt_config.clean_session = config_get_bool(mqtt, "clean_session", true);
    tcu->mqtt_config.qos = config_get_int(mqtt, "qos", 1);
    tcu->mqtt_config.retain = config_get_bool(mqtt, "retain", false);
    
    strncpy(tcu->mqtt_config.username, 
            config_get_string(mqtt, "username", ""), 
            sizeof(tcu->mqtt_config.username) - 1);
    
    strncpy(tcu->mqtt_config.password, 
            config_get_string(mqtt, "password", ""), 
            sizeof(tcu->mqtt_config.password) - 1);
    
    return 0;
}

static int load_data_config(tcu_t *tcu) {
    if (!tcu->config_manager.device_config) {
        return -1;
    }
    
    cJSON *data = cJSON_GetObjectItem(tcu->config_manager.device_config, "data");
    if (!data) {
        return -1;
    }
    
    tcu->data_config.report_interval = config_get_int(data, "report_interval", 30);
    tcu->data_config.max_properties_per_report = config_get_int(data, "max_properties_per_report", 10);
    tcu->data_config.enable_auto_register = config_get_bool(data, "enable_auto_register", true);
    tcu->data_config.enable_auto_reconnect = config_get_bool(data, "enable_auto_reconnect", true);
    tcu->data_config.reconnect_interval = config_get_int(data, "reconnect_interval", 5);
    tcu->data_config.max_reconnect_attempts = config_get_int(data, "max_reconnect_attempts", 10);
    
    return 0;
}

static void* data_report_thread_func(void *arg) {
    tcu_t *tcu = (tcu_t*)arg;
    
    LOG_INFO("数据上报线程启动");
    
    while (tcu->running) {
        // 模拟数据上报
        if (tcu->state == TCU_STATE_RUNNING) {
            cJSON *properties = cJSON_CreateObject();
            if (properties) {
                cJSON_AddNumberToObject(properties, "ua", 220.0 + (rand() % 20 - 10));
                cJSON_AddNumberToObject(properties, "ub", 220.0 + (rand() % 20 - 10));
                cJSON_AddNumberToObject(properties, "uc", 220.0 + (rand() % 20 - 10));
                cJSON_AddNumberToObject(properties, "Ia", 2.5 + (rand() % 10 - 5) * 0.1);
                cJSON_AddNumberToObject(properties, "Ib", 2.5 + (rand() % 10 - 5) * 0.1);
                cJSON_AddNumberToObject(properties, "Ic", 2.5 + (rand() % 10 - 5) * 0.1);
                
                tcu_report_properties(tcu, properties);
                cJSON_Delete(properties);
            }
        }
        
        sleep(tcu->data_config.report_interval);
    }
    
    LOG_INFO("数据上报线程退出");
    return NULL;
}

static void* heartbeat_thread_func(void *arg) {
    tcu_t *tcu = (tcu_t*)arg;
    
    LOG_INFO("心跳线程启动");
    
    while (tcu->running) {
        tcu->last_heartbeat = get_current_timestamp_ms();
        
        // 打印统计信息
        if (tcu_get_uptime(tcu) % 60 == 0) {
            tcu_print_stats(tcu);
        }
        
        sleep(10);
    }
    
    LOG_INFO("心跳线程退出");
    return NULL;
}

static int64_t get_current_timestamp_ms(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
